/*************************************************************************
 *
 * obsluhy handleru prikazu seriove komunikace
 * 
 * (c) Ales Povalac, alpov@alpov.net, http://www.alpov.net/
 * 
 *************************************************************************
 *
 * $Id: serial_hnds.c 60 2006-07-27 12:50:53Z alpov $
 * 
 *************************************************************************/         

#include <string.h>
#include <avr/io.h>
#include "../avrx/avrx.h"
#include "../avrx/AvrXFifo.h"
#include "serial.h"
#include "data.h"
#include "sensor.h"


/*************************************************************************
 * obsluha prikazu STDATA_READ
 *************************************************************************/ 
void STDATA_R_Handler(PACKET_HEADER *ph)
{
    void *buffer;
    unsigned char cpy_len;
    
    if (AvrXTestSemaphore(&SensorReady) != SEM_DONE)
        return;
    
    AvrXSetSemaphore(&SensorReady);
    
    if (ph->item_hi == ITEM_TEMPERATURE) {
        buffer = &stdata.temperature;
        cpy_len = sizeof(stdata.temperature);
    }
    else if (ph->item_hi == ITEM_STATE) {
        buffer = &stdata.io_state;
        cpy_len = sizeof(stdata.io_state) + sizeof(stdata.reg_state);
    }
    else if (ph->item_hi == ITEM_ALL) {
        buffer = &stdata;
        cpy_len = sizeof(stdata);
    }
    else
        return;
    
    ph->dest = ph->src;
    ph->src = ADDR_SERVER;
    ph->cmd = CMD_STDATA_WRITE;
    SerialSendPacket(ph, buffer, cpy_len, 1);
}


/*************************************************************************
 * obsluha prikazu RWDATA_WRITE
 *************************************************************************/ 
void RWDATA_W_Handler(PACKET_HEADER *ph, char *data, unsigned char length)
{
    void *buffer;
    unsigned char cpy_len;
    
    if (ph->item_hi == ITEM_MODE) {
        buffer = &rwdata.mode;
        cpy_len = sizeof(rwdata.mode);
    }
    else if (ph->item_hi == ITEM_SHIFT) {
        buffer = &rwdata.shift;
        cpy_len = sizeof(rwdata.shift) + sizeof(rwdata.shift_length);
    }
    else if (ph->item_hi == ITEM_SWITCH) {
        buffer = &rwdata.sw_mode;
        cpy_len = sizeof(rwdata.sw_mode) + sizeof(rwdata.sw_datetime);
    }
    else if (ph->item_hi == ITEM_RTC) {
        buffer = &rwdata.now;
        cpy_len = sizeof(rwdata.now);
    }
    else if (ph->item_hi == ITEM_ALL) {
        buffer = &rwdata;
        cpy_len = sizeof(rwdata);
    }
    else
        return;
    
    if (cpy_len != length)
        return;
    
    memcpy(buffer, data, cpy_len);                  // zapsat udaj

    if (ph->dest != ADDR_BROADCAST)
        SerialSendAck(ph);                          // potvrdit, pokud neni broadcast
}


/*************************************************************************
 * obsluha prikazu RWDATA_READ
 *************************************************************************/ 
void RWDATA_R_Handler(PACKET_HEADER *ph)
{
    void *buffer;
    unsigned char cpy_len;
    
    if (ph->item_hi == ITEM_MODE) {
        buffer = &rwdata.mode;
        cpy_len = sizeof(rwdata.mode);
    }
    else if (ph->item_hi == ITEM_SHIFT) {
        buffer = &rwdata.shift;
        cpy_len = sizeof(rwdata.shift) + sizeof(rwdata.shift_length);
    }
    else if (ph->item_hi == ITEM_SWITCH) {
        buffer = &rwdata.sw_mode;
        cpy_len = sizeof(rwdata.sw_mode) + sizeof(rwdata.sw_datetime);
    }
    else if (ph->item_hi == ITEM_RTC) {
        buffer = &rwdata.now;
        cpy_len = sizeof(rwdata.now);
    }
    else if (ph->item_hi == ITEM_ALL) {
        buffer = &rwdata;
        cpy_len = sizeof(rwdata);
    }
    else
        return;
    
    ph->dest = ph->src;
    ph->src = ADDR_SERVER;
    ph->cmd = CMD_RWDATA_WRITE;
    SerialSendPacket(ph, buffer, cpy_len, 1);
}

